package edu.towson.cosc.cosc455.cbrown.mdcomp;

import java.util.ArrayList;

public class MySemAnalyzer {
	//Array List of each line to be output into file
	ArrayList<String> output = new ArrayList<String>();
	ArrayList<String> ptree = new ArrayList<String>();
	String current; //current String being added to, used to separate lines
	int tPointer; //Used as a pointer for tokens in ptree
	
	public void start() throws CompilerException {
		tPointer = 0;
		current = "";
		ptree = MySynAnalyzer.ptree;
		String token;
		
		while (tPointer < ptree.size()) {
			//token is equal to the current token in the parse tree Array List
			token = ptree.get(tPointer);
			
			if(token.startsWith("#"))
				token = token.toUpperCase();
			
			//if-else-if statements to check for each tag and sent to methods accordingly
			if (token.contains("#") && token.contains("DOC"))
				document(token);
			else if (token.contains("#") && token.contains("HEAD"))
				head(token);
			else if (token.contains("#") && token.contains("TITLE"))
				title(token);
			else if (token.contains("#") && token.contains("PARA"))
				paragraph(token);
			else if (token.contains("#") && token.contains("BOLD"))
				bold(token);
			else if (token.contains("#") && token.contains("ITAL"))
				italics(token);
			else if (token.contains("#") && token.contains("LIST"))
				list(token);
			else if (token.contains("#") && token.contains("ITEM"))
				item(token);
			else if (token.contains("#") && token.contains("NEWLINE"))
				newline();
			else if (token.contains("#") && token.contains("AUDIO"))
				audio();
			else if (token.contains("#") && token.contains("VIDEO"))
				video();
			else if (token.equals("#START USE")) {
				tPointer +=2;
				use();
			}
			else if (token.equals("#START DEFINE"))
				tPointer += 6; //Skips over define because it is not actually used for anything
			else {
				current += token;
				tPointer++;
			}
		}
	}
	
	//Translates Document tags into html code
	public void document(String s) {
		if(s.startsWith("#START")) {
			output.add("<html>");
			tPointer++;
		}
		
		if(s.startsWith("#END")){
			output.add(current);
			output.add("</html>");
			tPointer++;
		}
	}
	
	//Translates Head tags into html code
	public void head(String s) {
		if(s.startsWith("#START")) {
			output.add("<head>");
			tPointer++;
		}
		
		if(s.startsWith("#END")){
			output.add(current);
			current = "";
			removeBlock("HEAD");
			output.add("</head>");
		}
	}
	
	//Translates Title tags into html code
	public void title(String s) {
		current = "<title>";
		tPointer++;
		
		current += ptree.get(tPointer);
		
		current += "</title>";
		tPointer++;
		removeBlock("TITLE");
	}
	
	//Translates Paragraph tags into html code
	public void paragraph(String s) {
		if(s.startsWith("#START")) {
			output.add("<p>");
			tPointer++;
		}
		
		if(s.startsWith("#END")){
			output.add(current);
			current = "";
			output.add("</p>");
			removeBlock("PARAGRAPH");
		}
	}
	
	//Translates Bold tags into html code
	public void bold(String s) {
		if(s.startsWith("#START")) {
			current += "<b>";
			tPointer++;
		}
		
		if(s.startsWith("#END")){
			current += "</b>";
			removeBlock("BOLD");
		}
	}
	
	//Translates Italics tags into html code
	public void italics(String s) {
		if(s.startsWith("#START")) {
			current += "<i>";
			tPointer++;
		}
		
		if(s.startsWith("#END")){
			current += "</i>";
			removeBlock("ITALICS");
		}
	}
	
	//Translates List tags into html code
	public void list(String s) {
		if(s.startsWith("#START")) {
			output.add(current);
			current ="";
			output.add("<ul>");
			tPointer++;
		}
		
		if(s.startsWith("#END")){
			output.add("</ul>");
			removeBlock("LIST");
		}
	}
	
	//Translates Item tags into html code
	public void item(String s) {
		if(s.startsWith("#START")) {
			current += "<li>";
			tPointer++;
		}
		
		if(s.startsWith("#END")){
			current += "</li>";
			output.add(current);
			current = "";
			removeBlock("ITEM");
		}
	}
	
	//Translates Newline tag into html code
	public void newline() {
		current += "<br>";
		output.add(current);
		current = "";
		tPointer++;
	}
	
	//Translates Audio tags into html code
	public void audio() {
		output.add(current);
		output.add("<audio controls>");
		current = "<source src=\"";
		
		tPointer++;
		
		current += ptree.get(tPointer).replace(" ", "");
		
		tPointer++;
		
		current += "\">";
		output.add(current);
		current = "";
		
		output.add("</audio>");
		tPointer++;
	}
	
	//Translates Video tags into html code
	public void video() {
		output.add(current);
		current = "<iframe src=\"";
		
		tPointer++;
		
		current += ptree.get(tPointer).replace(" ", "");
		
		tPointer++;
		
		current += "\"/>";
		output.add(current);
		current = "";
		
		tPointer++;
	}
	
	//Allows for scoping and variables
	//Checks through ptree for variable name and then replaces the variable with its value
	//Changes variable name to " " so that it will not be found again.
	public void use() throws CompilerException{
		String vName = ptree.get(tPointer - 1);
		String value;
		for (int i = tPointer - 2; i >= 0; i--) {
			if(ptree.get(i).equals("#END DEFINE")){
				value = ptree.get(i - 1);
				if(ptree.get(i - 3).equals(vName)) {
					current += value;
					tPointer++;
					return;
				}
			}
		}
		
		//If variable name can not be found, semantic error is printed
		String message = "Semantic Error: variable " + vName + " was never defined.";
		throw new CompilerException(message);
	}

	//Used to remove blocks so that static scoping can be accomplished.
	public void removeBlock(String s) {
		for (; tPointer >= 0; tPointer--) {
			if(ptree.get(tPointer).equalsIgnoreCase("#START " + s)) {
				ptree.remove(tPointer);
				return;
			}
			ptree.remove(tPointer);
		}
	}
}
